/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package compilador.analisadorLexico.automatos;

import compilador.analisadorLexico.CodeReader;
import compilador.tabelaDeSimbolos.Identificador;
import compilador.analisadorLexico.PalavraReservada;
import compilador.analisadorLexico.Token;
import compilador.analisadorLexico.TokenClass;

/**
 *
 * @author matheus.mcas
 */
public class AutomatoIdentificador implements IAutomato {

    //Expressão regular de definição: Letra{Letra|Digito|"_"}
    private final int INITIAL_STATE = 7; //estado inicial

    private final int ACCEPTANCE_STATE = 9; //estado de aceitação     

    private final int REJECTION_STATE = -1; //estado de rejeição

    private final String TOKEN_DEFINITION_ID = "ID";
    private final String TOKEN_DEFINITION_RW = "RW";
    private Token token;
    private Character currentChar;
    private String aceptedLexema;
    private CodeReader reader;
    private int index;
    private int state;

    public AutomatoIdentificador() {
        this.index = 0;
        this.currentChar = null;
        this.token = null;
        this.aceptedLexema = "";
        this.state = INITIAL_STATE;
    }

    public AutomatoIdentificador(CodeReader reader) {
        this.reader = reader;
        this.index = 0;
        this.currentChar = null;
        this.token = null;
        this.aceptedLexema = "";
        this.state = INITIAL_STATE;
    }

    public Token extraiToken() {
        
        resetAutomata();//O resetAutomata não era chamado se o automato retornasse null
        reader.clear();

        while (reader.hasChar() && state != REJECTION_STATE) {

            currentChar = reader.next();

            if (Character.isLetter(currentChar)) {
                if (state == INITIAL_STATE) {
                    state = 8;
                } else if (state == 8 || state == ACCEPTANCE_STATE) {
                    state = ACCEPTANCE_STATE;
                }
            } else if (Character.isDigit(currentChar) || currentChar.equals((Character) '_')) {
                if (state == INITIAL_STATE) {
                    state = REJECTION_STATE;
                    return null;
                } else if (state == 8 || state == ACCEPTANCE_STATE) {
                    state = ACCEPTANCE_STATE;
                }
            } else if(state == INITIAL_STATE || state == 8){
                state = REJECTION_STATE;
                return null;
            }else{
                 state = REJECTION_STATE;
            }

        }

        aceptedLexema = reader.closeToken();        
        PalavraReservada rw = PalavraReservada.checkRW(aceptedLexema);         
         
        if (rw != null) {
            token = new Token(TokenClass.PALAVRA_RESERVADA, rw,reader.getCurrentLine());
        } else {
            token = new Token(TokenClass.IDENTIFICADOR, new Identificador(aceptedLexema),reader.getCurrentLine());
        }

        //resetAutomata();
        return token;
    }

    public void resetAutomata() {
        index = 0;
        currentChar = null;
        aceptedLexema = "";
        state = INITIAL_STATE;
    }
}
